#ifndef __TASK_H
#define __TASK_H

#include <stdint.h>

// OS的配置文件
#include "osConfig.h"

// OS的内核库文件
#include "osLib.h"

// 任务的运行状态
#define OS_TASK_STA_READY       (1 << 0)        // 就绪态
#define OS_TASK_STA_DELAY       (1 << 1)        // 阻塞态
#define OS_TASK_STA_SUSPEND     (1 << 2)        // 挂起态

#define OS_TASK_STA_WAIT_MASK   (0xFF << 16)    // 事件类型掩码
#define OS_TASK_STA_WAIT_SEM    (1 << 16)       // 等待信号量事件      
#define OS_TASK_STA_WAIT_MSGBOX (1 << 17)       // 等待邮箱队列事件 
#define OS_TASK_STA_WAIT_MEM    (1 << 18)       // 等待存储块事件 
#define OS_TASK_STA_WAIT_FGROUP (1 << 19)       // 等待事件标志组事件 
#define OS_TASK_STA_WAIT_MUTEX  (1 << 20)       // 等待事件标志组事件 

// Cortex-M的堆栈单元类型：堆栈单元的大小为32位，所以使用uint32_t
typedef uint32_t tTaskStack;


typedef enum _OS_ERROR
{
    OS_NOERROR = 0,         // 无错误
    OS_TIMEOUT,             // 超时
    OS_FORCE_DEL,           // 任务被强制删除
    OS_ERROR_NORESOURCE,    // 无资源可用
    OS_ERROR_OWNER,         // 非法调用者
} OS_ERROR_T;


/* 前向引用， 给出结构体名，不做结构体定义, 其他地方进行定义
 * 在用作指针使用时，不会报错 
 **/
struct _EVENT;

/**
 * @brief TASK_T 任务结构体，包含了一个任务的所有信息。
 */
typedef struct _TASK_T
{
    uint32_t        *stackBase;         /* 堆栈的起始地址*/
    uint32_t        stackSize;          /* 堆栈大小*/   
    tTaskStack      *stack;             /* 任务所用堆栈的堆栈指针*/
    
    uint32_t        prio;               /* 任务的优先级*/
    uint32_t        state;              /* 任务运行状态*/
    
    NODE_T          taskLinkNode;       /* 任务链接队列节点*/
    uint32_t        slice;              /* 当前剩余时间片*/
    
    NODE_T          taskDelayNode;      /* 任务延时队列节点*/
    uint32_t        delayTicks;         /* 任务延时计数器*/
    
    uint32_t        suspendCount;       /* 任务被挂起的次数*/
    
    void            (*clean)(void *param); /* 任务清理函数*/
    void            *cleanParam;        /* 任务清理函数的形参*/
    uint8_t         requestDeleteFlag;  /* 请求删除任务标志*/
    
    struct _EVENT   *waitEvent;         /* 任务正在等待的事件类型*/
    void            *eventMsg;          /* 等待事件的消息存储位置*/
    uint32_t        waitEventResult;    /* 等待事件的结果*/
    
    uint32_t        waitFlagType;       /* 等待的事件标志组类型*/
    uint32_t        eventFlags;         /* 等待的事件标志组结果*/
    
                
} TASK_T;



typedef struct _TASK_INFO_T
{
    uint32_t    prio;               /* 任务的优先级*/
    uint32_t    state;              /* 任务运行状态*/
    uint32_t    slice;              /* 当前剩余时间片*/
    uint32_t    delayTicks;         /* 任务延时计数器*/
    uint32_t    suspendCount;       /* 任务被挂起的次数*/
    
    uint32_t    stackSize;          /* 堆栈空间大小*/

#if OS_ENABLE_TRACE_STACK == 1
    uint32_t    stackFree;          /* 剩余堆栈空间大小*/
#endif // OS_ENABLE_TRACE_STACK == 1
    
} TASK_INFO_T;



extern TASK_T   *curTask;           /* 当前任务*/

extern void     vTaskSchedInit(void);
extern void     vTaskCreate(TASK_T *task, void (*entry)(void *), void *param, uint32_t prio, tTaskStack *stack, uint32_t stackSize);
extern void     vTaskStartScheduler(void);
extern void     vTaskYield(void);
extern TASK_T * vTaskHighestReady(void);


extern void     vTaskReadyListAdd(TASK_T *task);
extern void     vTaskReadyListDel(TASK_T *task);
extern void     vTaskDelayListAdd(TASK_T *task, uint32_t ticks);
extern void     vTaskDelayListDel(TASK_T *task);
extern void     vTaskDelay(uint32_t ticks);
extern void     vTaskSystemTickHandle(void);
extern void     vTaskGetInfo(TASK_T *task, TASK_INFO_T *info);


extern void     vTaskSchedDisable(void);
extern void     vTaskSchedEnable(void);

extern void     vTaskSuspend(TASK_T *task);
extern void     vTaskResume(TASK_T *task);

extern void     vTaskSetCleanCallFunc(TASK_T *task, void (*clean)(void *), void *param);
extern void     vTaskRequestDelete(TASK_T *task);
extern uint8_t  vTaskIsRequestDelete(void);
extern void     vTaskDeleteSelf(void);
extern void     vTaskForceDelete(TASK_T *task);



__weak void idleTaskEntry(void *param);



#endif // __TASK_H
